<?php declare(strict_types=1);

/**
 * @author      guosir
 * @copyright   2023-2025 owner
 **/

namespace Srv\Apps\Apis\Promotion\Ctl;

use Srv\Apps\Apis\Common\Ctl\DevicePushCtl;
use Srv\Apps\Apis\Common\DefCtl\DefChannelCtl;
use Srv\Apps\Apis\Common\DefCtl\DefDeviceLangCtl;
use Srv\Apps\Apis\Common\DefCtl\DefDeviceModelCtl;
use Srv\Apps\Apis\Common\DefCtl\DefDeviceOsCtl;
use Srv\Apps\Apis\Common\DefCtl\DefPlatformCtl;
use Srv\Apps\Apis\Common\IdxCtl\IdxIp;
use Srv\Apps\Apis\Skit\Ctl\SkitInfoCtl;
use Srv\Apps\Apis\User\Ctl\UserCtl;
use Srv\Apps\Proto\DTO\Promotion\PutRequestListDTO;
use Srv\Apps\Proto\VO\Promotion\PutRequestListVO;
use Srv\Apps\Proto\VO\Promotion\PutRequestVO;
use Srv\Apps\Proto\VO\Skit\SkitInfoVO;
use Srv\Apps\Proto\VO\User\UserInfoBasicVO;
use Srv\Libs\Common\CommArray;
use Srv\Libs\Frame\ControllerAbstract;
use Srv\Libs\Frame\Page;
use Srv\Libs\Storage\DataMysql;
use Srv\Libs\Tools\IpAddr;

final class PutRequestCtl extends ControllerAbstract
{
    private ?DataMysql $DbAuto              = null;     // DB-Write



    /**
     * @return static
     * tag
     */
    final public static function tag():self
    {
        $thisObject                         = self::tagGet();
        if($thisObject instanceof self){
            $thisObject->DbAuto             = self::getDbAuto();
        }
        return $thisObject;
    }

    /**
     * @param int $ptrrId
     * @return array
     * getPutRequestSrc
     */
    public function getPutRequestSrc(int $ptrrId):array
    {
        if($ptrrId < 1) return [];
        $isFail     = false;
        $info       = $this->DbAuto->getDataOne('SELECT ptrr_id, ptlr_id, skio_id, ptrr_uuid, ptrr_ip, dcht_id, ua_id, ddpt_id, ddlt_id, ddot_id, ddmt_id, ptrr_width, ptrr_height, wifb_id, wimd_id, wise_id, wiui_id, wict_id, witm_id, wicn_id, user_id_match, ptrr_match_time, ptrr_create_day_time, ptrr_create_time FROM '.$this->DbAuto->getTableNameAll('put_request_record').' WHERE ptrr_id='.$ptrrId, $isFail);
        if($isFail || !isset($info['ptrr_id'])) return [];
        return $info;
    }

    /**
     * @param Page $Page
     * @param array $whereData
     * @return PutRequestListVO|null
     * getPutRequestList
     */
    public function getPutRequestList(Page $Page, array $whereData): ?PutRequestListVO
    {
        $limitString            = $Page->getLimitString();
        $whereString            = ' WHERE 1 ';
        // 检索条件
        if(count($whereData) > 0)foreach ($whereData as $key => $val){
            switch ($key){
                case PutRequestListDTO::_ptrrId:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'ptrr_id='. intval($val);
                    break;
                case PutRequestListDTO::_ptlrId:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'ptlr_id='. intval($val);
                    break;
                case PutRequestListDTO::_skioId:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'skio_id='. intval($val);
                    break;
                case PutRequestListDTO::_createDayTime:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'ptrr_create_day_time='. intval($val);
                    break;
                case PutRequestListDTO::_uuid:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'ptrr_uuid=\''.$this->DbAuto->getRealEscapeString($val).'\'';
                    break;

                case PutRequestListDTO::_putChannel:
                    if($val === '1'){
                        $whereString    .= (strlen($whereString)>0?' AND ':'').'LENGTH(ptrr_chnl)>0';
                    }else{
                        $whereString    .= (strlen($whereString)>0?' AND ':'').'ptrr_chnl LIKE \''.$this->DbAuto->getRealEscapeString($val).'%\'';
                    }
                    break;
                case PutRequestListDTO::_pixelId:
                    if($val === '1'){
                        $whereString    .= (strlen($whereString)>0?' AND ':'').'LENGTH(ptrr_pixel_id)>0';
                    }else{
                        $whereString    .= (strlen($whereString)>0?' AND ':'').'ptrr_pixel_id LIKE \''.$this->DbAuto->getRealEscapeString($val).'%\'';
                    }
                    break;
                case PutRequestListDTO::_idNum:
                    if(strlen($val) > 10 && is_numeric($val)){
                        $whereString    .= (strlen($whereString)>0?' AND ':'').'user_id_match='.intval($val);
                    }else{
                        $tempSql        = 'SELECT user_id FROM '.$this->DbAuto->getTableNameAll('user_info').' WHERE usi_idnum LIKE \'%'.$this->DbAuto->getRealEscapeString($val).'%\' AND usi_delete=0';
                        $whereString    .= (strlen($whereString)>0?' AND ':'').'user_id_match IN('.$tempSql.')';
                    }
                    break;
                case PutRequestListDTO::_createTimeStart:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'ptrr_create_time>='. intval($val);
                    break;
                case PutRequestListDTO::_createTimeStop:
                    $whereString        .= (strlen($whereString)>0?' AND ':'').'ptrr_create_time<='. intval($val);
                    break;
            }
        }
        $isFail                 = false;
        $sql                    = 'SELECT SQL_CALC_FOUND_ROWS ptrr_id, ptlr_id, skio_id, ptrr_uuid, ptrr_pixel_id, ptrr_chnl, ptrr_ip, dcht_id, ua_id, ddpt_id, ddlt_id, ddot_id, ddmt_id, ptrr_width, ptrr_height, wifb_id, wimd_id, wise_id, wiui_id, wict_id, witm_id, wicn_id, user_id_match, ptrr_match_time, ptrr_create_day_time, ptrr_create_time FROM '.$this->DbAuto->getTableNameAll('put_request_record').$whereString.' ORDER BY ptrr_id DESC '.$limitString;
        $list                   = $this->DbAuto->getData($sql, $isFail);
        $totalNum               = $this->DbAuto->getDataInt('SELECT FOUND_ROWS() as num', 'num');
        if($isFail) return null;
        $PutRequestVOList       = [];
        if(CommArray::isForeach($list)){
            $DevicePushCtl      = DevicePushCtl::tag();
            $DefPlatformCtl     = DefPlatformCtl::tag();
            $DefDeviceLangCtl   = DefDeviceLangCtl::tag();
            $DefDeviceOsCtl     = DefDeviceOsCtl::tag();
            $DefDeviceModelCtl  = DefDeviceModelCtl::tag();
            $UserCtl            = UserCtl::tag();
            $skioIdList         = array_map('intval', array_unique(array_column($list, 'skio_id')));
            $SkitInfoVOList     = SkitInfoCtl::tag()->getSkitInfoBatch($skioIdList);
            $uaIdList           = array_map('intval', array_unique(array_column($list, 'ua_id')));
            $uaSrcList          = $DevicePushCtl->getUaByIdBatch($uaIdList);
            $ddptIdList         = array_map('intval', array_unique(array_column($list, 'ddpt_id')));
            $devicePlatformList = $DefPlatformCtl->getExtStrByIdBatch($ddptIdList, $DefPlatformCtl::EXT_NAME);
            $ddltIdList         = array_map('intval', array_unique(array_column($list, 'ddlt_id')));
            $deviceLangList     = $DefDeviceLangCtl->getExtStrByIdBatch($ddltIdList, $DefDeviceLangCtl::EXT_NAME);
            $ddotIdList         = array_map('intval', array_unique(array_column($list, 'ddot_id')));
            $deviceOsList       = $DefDeviceOsCtl->getExtStrByIdBatch($ddotIdList, $DefDeviceOsCtl::EXT_NAME);
            $ddmtIdList         = array_map('intval', array_unique(array_column($list, 'ddmt_id')));
            $deviceModeList     = $DefDeviceModelCtl->getExtStrByIdBatch($ddmtIdList, $DefDeviceModelCtl::EXT_NAME);
            $userIdMatchList    = array_map('intval', array_unique(array_column($list, 'user_id_match')));
            $UserInfoBasicList  = $UserCtl->getUserInfoBasicBatch($userIdMatchList);
            foreach($list as $info){
                $ptrrIdItem             = intval($info['ptrr_id']??0);
                if($ptrrIdItem < 1) continue;
                $PutRequestVO           = $this->getPutRequestVO($info);
                if(!($PutRequestVO instanceof PutRequestVO)) continue;
                $skioIdItem             = intval($info['skio_id']);
                $SkitInfoVO             = $SkitInfoVOList[$skioIdItem]??null;
                if($SkitInfoVO instanceof SkitInfoVO) {
                    $PutRequestVO->setSkitInfo($SkitInfoVO);
                }
                $PutRequestVO->setUa($uaSrcList[intval($info['ua_id'])]??'');
                $PutRequestVO->setPlatform($devicePlatformList[intval($info['ddpt_id'])]??'');
                $PutRequestVO->setDeviceLang($deviceLangList[intval($info['ddlt_id'])]??'');
                $PutRequestVO->setDeviceOs($deviceOsList[intval($info['ddot_id'])]??'');
                $PutRequestVO->setDeviceMode($deviceModeList[intval($info['ddmt_id'])]??'');
                $userIdMatch            = intval($info['user_id_match']);
                $UserInfoBasicVO        = $UserInfoBasicList[$userIdMatch]??null;
                if($UserInfoBasicVO instanceof UserInfoBasicVO) $PutRequestVO->setUserInfoBasicMatch($UserInfoBasicVO);
                $PutRequestVOList[]     = $PutRequestVO;
            }
        }
        $PutRequestListVO               = new PutRequestListVO();
        $PutRequestListVO->setList($PutRequestVOList);
        $PutRequestListVO->setPage($Page->getPageVO($totalNum));
        return $PutRequestListVO;
    }

    /**
     * @param int $ptrrId
     * @return PutRequestVO|null
     * getPutRequestInfo
     */
    public function getPutRequestInfo(int $ptrrId):?PutRequestVO
    {
        $infoSrc    = $this->getPutRequestSrc($ptrrId);
        if(!isset($infoSrc['ptrr_id'])) return null;
        return $this->getPutRequestVO($infoSrc);
    }

    /**
     * @param array $info
     * @return PutRequestVO|null
     * getPutRequestVO
     */
    public function getPutRequestVO(array $info):?PutRequestVO
    {
        $ptrrId             = intval($info['ptrr_id']??0);
        if($ptrrId < 1) return null;
        $PutRequestVO       = new PutRequestVO();
        $PutRequestVO->setPtrrId($ptrrId);
        $PutRequestVO->setPtlrId(intval($info['ptlr_id']));
        $PutRequestVO->setSkioId(intval($info['skio_id']));
        $PutRequestVO->setUuid(trim($info['ptrr_uuid']));
        $PutRequestVO->setPixelId(trim($info['ptrr_pixel_id']));
        $PutRequestVO->setPutChannel(trim($info['ptrr_chnl']));
        $ipStr              = IdxIp::tag()->getIpStrByIntStr($info['ptrr_ip']);
        $ipArea             = IpAddr::getLocationInfo($ipStr);
        $PutRequestVO->setIpStr($ipStr.'('.($ipArea['country']??'-').')');
        $dchtId             = intval($info['dcht_id']);
        if($dchtId > 0){
            $channel        = DefChannelCtl::tag()->getExtStrById($dchtId, DefChannelCtl::EXT_NAME);
            $PutRequestVO->setChannel($channel);
        }
        $PutRequestVO->setDeviceWidth(intval($info['ptrr_width']));
        $PutRequestVO->setDeviceHeight(intval($info['ptrr_height']));
        $PutRequestVO->setUserIdMatch(intval($info['user_id_match']));
        $PutRequestVO->setMatchTime(intval($info['ptrr_match_time']));
        $PutRequestVO->setCreateDayTime(intval($info['ptrr_create_day_time']));
        $PutRequestVO->setCreateTime(intval($info['ptrr_create_time']));
        return $PutRequestVO;
    }
}